<%
  product_name = object.__product.name
  has_project = object.base_url.include?("{{project}}")
-%>
<%= lines(autogen_notice(:go, pwd)) -%>
package google

import (
  "fmt"
)

type <%= product_name -%>OperationWaiter struct {
  Config    *Config
  UserAgent string
<% if has_project -%>
  Project string
<% end -%>
  CommonOperationWaiter
}

func (w *<%= product_name -%>OperationWaiter) QueryOp() (interface{}, error) {
  if w == nil {
    return nil, fmt.Errorf("Cannot query operation, it's unset or nil.")
  }
  // Returns the proper get.
  url := fmt.Sprintf("<%= [object.__product.base_url, async.operation.base_url].flatten.join.gsub('{{op_id}}', '%s') -%>", w.CommonOperationWaiter.Op.Name)

  return sendRequest(w.Config, "GET", <% if has_project %>w.Project<% else %>""<% end %>, url, w.UserAgent, nil<%= object.error_retry_predicates ? ", " + object.error_retry_predicates.join(',') : "" -%>)
}

func create<%= product_name %>Waiter(config *Config, op map[string]interface{}, <% if has_project -%> project, <% end -%> activity, userAgent string) (*<%=product_name%>OperationWaiter, error) {
  w := &<%= product_name -%>OperationWaiter{
    Config:    config,
    UserAgent: userAgent,
<% if has_project -%>
    Project: project,
<% end -%>
  }
  if err := w.CommonOperationWaiter.SetOp(op); err != nil {
    return nil, err
  }
  return w, nil
}

<% if async.result.resource_inside_response -%>
<%# Not all APIs will need a WithResponse operation, but it's hard to check whether
    they will or not since it involves iterating over all resources.
    Might as well just nolint it so we can pass the linter checks.
-%>
// nolint: deadcode,unused
func <%= product_name.camelize(:lower) -%>OperationWaitTimeWithResponse(config *Config, op map[string]interface{}, response *map[string]interface{},<% if has_project -%> project,<% end -%> activity, userAgent string, timeout time.Duration) error {
  w, err := create<%= product_name %>Waiter(config, op, <% if has_project -%> project, <%end-%> activity, userAgent)
  if err != nil {
      return err
  }
  if err := OperationWait(w, activity, timeout, config.PollInterval); err != nil {
      return err
  }
  return json.Unmarshal([]byte(w.CommonOperationWaiter.Op.Response), response)
}
<% end -%>

func <%= product_name.camelize(:lower) -%>OperationWaitTime(config *Config, op map[string]interface{}, <% if has_project -%> project,<% end -%> activity, userAgent string, timeout time.Duration) error {
  if val, ok := op["name"]; !ok || val == "" {
    // This was a synchronous call - there is no operation to wait for.
    return nil
  }
  w, err := create<%= product_name %>Waiter(config, op, <% if has_project -%> project, <%end-%> activity, userAgent)
  if err != nil {
      // If w is nil, the op was synchronous.
      return err
  }
  return OperationWait(w, activity, timeout, config.PollInterval)
}
